/**
 * @file main.cpp
 * @author Scanagatta Mauro - Alberto Franco
 *
 * Contains program entry point.
 */
#include <cstdlib>
#include <iostream>
#include <vector>
#include <fstream>
#include <string>

#include "UpgmaAlgorithm.h"
#include "ClustalWSample.h"
#include "NewickTree.h"
#include "NewickTreeFactory.h"
#include "FastaHandler.h"

/// Program main function. The execution starts from here.
int main (int argc, char const *argv[])
{
    if (argc < 2) 
    {
        std::cout << "Bad agrs. \nUsage: bdbm5 [FASTA file]" << endl;
    }
	else try
	{
	    using namespace Biopool;
        /// Sequences to align, stored in a vector
        std::vector<std::string> sequences(0);
        // readSequences(sequences);
        /// Read the fasta file.
        std::vector<FastaHandler::FastaPair> readFile;
        FastaHandler fastaHandler;
        fastaHandler.readFasta(readFile, argv[1]);
        sequences = FastaHandler::vectorFromFasta(readFile);
        
        if (sequences.size() < 2)
        {
            std::cout << "No alignment to do. Exiting.\n";
            return 0;
        }
        
        /// Print input sequences
        std::cout << "Printing input sequences... " << std::endl;
        for (unsigned int i = 0; i < sequences.size(); i++)
        {
            std::cout << "   Sequence #" << i << '\t' 
                      << sequences[i] << std::endl;
        }

        /// Invoke Upgma
        UpgmaAlgorithm upgma(sequences);
        std::string evolTree = upgma.execute();
        cout << "\n Evolutionary Tree calculated by UPGMA: \n" 
             << evolTree << std::endl;

        /// Invoke multiple alignment
        ClustalWSample clustal(evolTree, sequences);
        std::vector<std::string> fastaAlignment = clustal.execute();

        std::cout << "\n FASTA format by clustalW: \n" << std::endl;

        readFile = FastaHandler::vectorToFasta(fastaAlignment);
        cout << fastaHandler.writeFasta(readFile);
            
	} 
	catch( char const * str ) 
	{
        std::cout << "\nException raised: " << str << std::endl;
	} 

	return 0;
}

